from Map.point import point
import time
import copy
import constant


class map(object):
    def __init__(self):
        # map 二位列表 保存第几行第几列的点
        self.map = []
        self.points = []
        self.init_point()
        self.init_edge()

    def init_point(self):
        # 初始信息
        id = 0
        len_b = constant.len_b
        # 添加第一行岸吊的位置节点
        qc_x = [len_b * 4, len_b * 8, len_b * 12, len_b * 20, len_b * 24, len_b * 28]
        # type 的类型  0：岸吊点  1：双向节点    2：单向节点
        y, type = 0, 0
        row = []
        for i in range(0, 6):
            po = point(id, qc_x[i], y, type)
            id += 1
            row.append(po)
        self.map.append(row)
        # 添加第一行双向节点
        x, y, type = len_b/2, len_b*2.25, 1
        row = []
        for i in range(0, 4):
            po = point(id, x, y, type)
            id += 1
            x += len_b * 11
            row.append(po)
        self.map.append(row)
        # 添加连续的四行堆场节点
        x, y, type = len_b/2, len_b * 4.75, 2
        for i in range(0, 4):
            row = []
            for i in range(0, 4):
                po = point(id, x, y, type)
                x += len_b * 11
                id += 1
                row.append(po)
            y += len_b * 2.5
            x = len_b/2
            self.map.append(row)
        # 添加第五行双向节点
        x, y, type = len_b/2, len_b * 15, 1
        row = []
        for i in range(0, 4):
            po = point(id, x, y, type)
            id += 1
            x += len_b * 11
            row.append(po)
        self.map.append(row)
        # 添加连续的四行堆场节点
        x, y, type = len_b/2, len_b * 17.75, 2
        for i in range(0, 4):
            row = []
            for i in range(0, 4):
                po = point(id, x, y, type)
                x += len_b * 11
                id += 1
                row.append(po)
            y += len_b * 2.5
            x = len_b/2
            self.map.append(row)
        # 添加第最后一行双向节点
        x, y, type = len_b/2, len_b*28, 1
        row = []
        for i in range(0, 4):
            po = point(id, x, y, type)
            id += 1
            x += len_b * 11
            row.append(po)
        self.map.append(row)
        # 打印节点信息
        for row in self.map:
            for i in row:
                self.points.append(i)
                print("(", i.x,i.y, ")", end=" ")
            print(" ")

    def init_edge(self):
        # 第一行，六个泊位节点建双向边
        for i in range(0, len(self.map[0]) - 1):
            if i == 2:
                continue
            from_point, to_point = self.map[0][i], self.map[0][i + 1]
            from_point.add_edge(from_point.num_id, to_point.num_id,
                                abs(from_point.x - to_point.x) + abs(from_point.y - to_point.y),1)
            to_point.add_edge(to_point.num_id, from_point.num_id,
                              abs(from_point.x - to_point.x) + abs(from_point.y - to_point.y),1)
        # 泊位节点与第一行双向节点的建双向边
        temp_row = [self.map[0][0], self.map[0][2], self.map[0][3], self.map[0][5]]
        for i in range(len(temp_row)):
            from_point, to_point = temp_row[i], self.map[1][i]
            from_point.add_edge(from_point.num_id, to_point.num_id,
                                abs(from_point.x - to_point.x) + abs(from_point.y - to_point.y),1)
            to_point.add_edge(to_point.num_id, from_point.num_id,
                              abs(from_point.x - to_point.x) + abs(from_point.y - to_point.y),1)
        # 每一行的节点与下一行建双向边
        for j in range(1, len(self.map) - 1):
            for i in range(0, len(self.map[j])):
                from_point, to_point = self.map[j][i], self.map[j + 1][i]
                from_point.add_edge(from_point.num_id, to_point.num_id,
                                    abs(from_point.x - to_point.x) + abs(from_point.y - to_point.y),1)
                to_point.add_edge(to_point.num_id, from_point.num_id,
                                  abs(from_point.x - to_point.x) + abs(from_point.y - to_point.y),1)
        # 每一行的节点与同行下一个节点建立单向边
        for j in range(1, len(self.map)):
            for i in range(0, len(self.map[j]) - 1):
                from_point, to_point = self.map[j][i], self.map[j][i + 1]
                if(j==1 or j==6 or j==11):
                    from_point.add_edge(from_point.num_id, to_point.num_id,
                                    abs(from_point.x - to_point.x) + abs(from_point.y - to_point.y),1)
                else:
                    from_point.add_edge(from_point.num_id, to_point.num_id,
                                    abs(from_point.x - to_point.x) + abs(from_point.y - to_point.y),0)
                
        # 第1，6，11行建立双向边
        j = 1
        for i in range(0, len(self.map[j]) - 1):
            from_point, to_point = self.map[j][i], self.map[j][i + 1]
            to_point.add_edge(to_point.num_id, from_point.num_id,
                              abs(from_point.x - to_point.x) + abs(from_point.y - to_point.y),1)
        j = 6
        for i in range(0, len(self.map[j]) - 1):
            from_point, to_point = self.map[j][i], self.map[j][i + 1]
            to_point.add_edge(to_point.num_id, from_point.num_id,
                              abs(from_point.x - to_point.x) + abs(from_point.y - to_point.y),1)
        j = 11
        for i in range(0, len(self.map[j]) - 1):
            from_point, to_point = self.map[j][i], self.map[j][i + 1]
            to_point.add_edge(to_point.num_id, from_point.num_id,
                              abs(from_point.x - to_point.x) + abs(from_point.y - to_point.y),1)
        # #打印每个节点的边数
        # for i in self.map:
        #     for j in i:
        #         print(len(j.edges),end="")
        #     print(" ")

    # def cal_end_time(self, st, l):
    #     tem = l / constant.speed
    #     if tem - int(l / constant.speed) > 0:
    #         tem += 1
    #     return int(st + tem)

    # def find_path(self, x, y):
    #     dis = [999999999 for i in range(0, 60)]
    #     tim = [999999999 for i in range(0, 60)]
    #     bo = [False for i in range(0, 60)]
    #     path = [0 for i in range(0, 60)]
    #     path[x] = x
    #     bo[x] = True
    #     dis[x], tim[x] = 0, 0
    #     que = []
    #     po = copy.deepcopy(self.points)
    #     que.append(po[x])
    #     l, r = -1, 0
    #     while (l < r):
    #         l += 1
    #         qo = que[l]
    #         bo[qo.num_id] = False
    #         for i in qo.edges:
    #             to_point = i.to_point_id
    #             star_tim = int(tim[qo.num_id])
    #             end_tim = self.cal_end_time(star_tim, i.length)
    #             cro_time = i.find_timewind(star_tim, end_tim)
    #             if (tim[to_point] > end_tim + cro_time):
    #                 tim[to_point] = end_tim + cro_time
    #                 i.add_timewind(star_tim, end_tim + cro_time)
    #                 dis[to_point] = dis[qo.num_id] + i.length
    #                 path[to_point] = qo.num_id
    #                 if (bo[to_point] == False):
    #                     r += 1
    #                     bo[to_point] = True
    #                     que.append(po[to_point])
    #     xx = y
    #     path_1 = []
    #     while (xx != x):
    #         path_1.append(xx)
    #         xx = path[xx]
    #     path_1.append(xx)
    #     for j in range(len(path_1) - 1, 0, -1):
    #         sp = path_1[j]
    #         for i in self.points[sp].edges:
    #             if i.to_point_id == path_1[j - 1]:
    #                 i.add_timewind(tim[sp], tim[i.to_point_id])
    #             # print("##: ",sp,i.to_point_id,tim[sp],tim[i.to_point_id],"$$$",i.time_windows[0:20])
    #     # print(path_1[len(path_1) - 1::-1])
    #     #print("*****", x, y, dis[y], tim[y], "*****")

    def find_path(self, x, y):
        dis = [999999999 for i in range(0, 60)]
        tim = [999999999 for i in range(0, 60)]
        bo = [False for i in range(0, 60)]
        path = [0 for i in range(0, 60)]
        path[x] = x
        bo[x] = True
        dis[x], tim[x] = 0, 0
        que = []
        po = copy.deepcopy(self.points)
        que.append(po[x])
        l, r = -1, 0
        while (l < r):
            l += 1
            qo = que[l]
            bo[qo.num_id] = False
            for i in qo.edges:
                to_point = i.to_point_id
                cost_time=i.cost_time
                if (tim[to_point] > tim[qo.num_id] + cost_time):
                    tim[to_point] = tim[qo.num_id] + cost_time
                    dis[to_point] = dis[qo.num_id] + i.length
                    path[to_point]=qo.num_id
                    if (bo[to_point] == False):
                        r += 1
                        bo[to_point] = True
                        que.append(po[to_point])   
        xx = y
        path_1 = []
        while (xx != x):
            path_1.append(xx)
            xx = path[xx]
        path_1.append(xx)
        return dis[y],tim[y],path_1
        


if __name__ == "__main__":
    mm = map()
    start_time = time.time()
    for i in range(len(mm.points)):
        print("第 {} 个point的边的花费 ".format(i),end=" ")
        for j in mm.points[i].edges:
            print(j.cost_time,end=" ")
        print(" ")
    end_time = time.time()
    print("花费了：", end_time - start_time, " s")
